package devcamp.team;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;

import devcamp.team.connection.WowoooooooAsyncTask;
import devcamp.team.data.WowoooooooUserData;
import devcamp.team.util.DialogUtils;
import devcamp.team.util.PinItemOverlay;
import devcamp.team.util.PreferenceUtils;
import devcamp.team.util.WowoooooooUtils;

/**
 * 本アプリケーションのメインアクティビティ.
 * 
 * @author noriko.taki3
 *
 */
public class DevCampTeamAActivity extends MapActivity {

    private static final String TAG = "DevCampTeamAActivity";
    // 更新通知する間隔（ミリ秒単位）
    private static final long MIN_TIME = 60000;// テスト用１分
    // 更新通知する移動距離（メートル単位）
    private static final float MIN_DISTANCE = 5F;// テスト用5m 

    private MapView map;
    private MapController controller;
    private LocationManager manager;
    private String bestProvider;
    private Location currentLocation = null;
    private float latitude, longitude;
    private String locationName;
    private PreferenceUtils preference;


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	Log.d(TAG, "onCreate");    	
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        // MapView
        LinearLayout l = (LinearLayout) findViewById(R.id.topmap);
        try {
	        LinearLayout l2 = (LinearLayout) getLayoutInflater().inflate(R.layout.mapview, null);
	        map = (MapView) l2.findViewById(R.id.mymap);
	        
	        Log.d(TAG, "child count : " + l.getChildCount()); 
	       
	        l.addView(l2);
	        
	        Log.d(TAG, "child count : " + l.getChildCount()); 
        } catch (Exception e) {
        	e.printStackTrace();
        }
    }
 
	/**
     * 画面の構成要素を初期化する.
     */
    @Override
    protected void onResume() {
    	Log.d(TAG, "onResume");  	
        super.onResume();
        initViewLayout();
    }

    /**
     * 中断直前処理
     */
    @Override
    protected void onPause() {
    	Log.d(TAG, "onPause");
        super.onPause();

        // 位置情報のｌ更新を停止
        if (manager != null && WowoooooooUtils.validate(bestProvider)) {
        	manager.removeUpdates(locationListener);
        }
    }
    

    /**
     * 以下の画面の構成要素を初期化する.
     * <ul>
     * <li>MapView</li>
     * <li>設定ボタン</li>
     * <li>Wowooooooo! ボタン</li>
     * </ul>
     * 
     */
    private void initViewLayout() {
    	
        // SharedPreferences 設定情報
        preference = new PreferenceUtils(getApplicationContext());
        if (preference.getUniqueId() == -1) {
            // 未保存時の場合：事前にメッセージ出すなら
        	Toast.makeText(DevCampTeamAActivity.this, getResources().getString(R.string.dialog_error_wowooooooo_message), Toast.LENGTH_LONG).show();
        } else {
        	// Hello! nickName
        	TextView hello = (TextView) findViewById(R.id.hello);
        	hello.setText(String.format("%s  %s", getResources().getString(R.string.hello), preference.getNickName()));
        	hello.setVisibility(View.VISIBLE);
        	//Toast.makeText(DevCampTeamAActivity.this, getResources().getString(R.string.hello) + preference.getNickName(), Toast.LENGTH_LONG).show();
        }
        

        // title ﾊﾞｰ
        WowoooooooUtils.setTitle(this);

        // MapView 
        Log.d(TAG, "map : " + map.toString());
        LinearLayout l = (LinearLayout) findViewById(R.id.topmap);
        int count = l.getChildCount();
        Log.d(TAG, "child count : " + count); 
        if (count < 1) {
        	// mapが描画できない場合
        	//　inflateでは例外発生してしまう。
        	View l2 = (View) map.getParent();
        	l.addView(l2);
	        
	        Log.d(TAG, "child count : " + l.getChildCount()); 
        }
        map.setBuiltInZoomControls(true);
        
        controller = map.getController();

        manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        // 現在地情報が使用可能な設定にまっているかどうか確認
        if (!manager.isProviderEnabled(Context.LOCATION_SERVICE)) {
            // 実機でのみ有効(有効にするように促す)
            /*
            DialogUtils.AlertDialogOk2action(
            		DevCampTeamAActivity.this, 
            		getResources().getString(R.string.dialog_location_titile), 
            		getResources().getString(R.string.dialog_location_message),
            		Settings.ACTION_LOCATION_SOURCE_SETTINGS)
            		.show();
            	
            	*/
        }

        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_FINE);// 精度
        criteria.setAltitudeRequired(false);// 標高
        criteria.setBearingRequired(false);// 進行方向
        criteria.setCostAllowed(false);// 位置情報取得に費用発生
        criteria.setPowerRequirement(Criteria.POWER_LOW);// 消費電力

        bestProvider = manager.getBestProvider(criteria, true);
        Log.d(TAG, "best Proviser : " + bestProvider);

        // 現在地情報が使用可能な設定になっているかどうか確認
        if (!WowoooooooUtils.validate(bestProvider)) {

            Log.d(TAG, "best Proviser Error!");

            // GPS or 無線ネットワークを有効にするように促す
            DialogUtils.AlertDialogOk2action(DevCampTeamAActivity.this, getResources().getString(R.string.dialog_location_titile), getResources().getString(R.string.dialog_location_message), Settings.ACTION_LOCATION_SOURCE_SETTINGS).show();
        } else {
            // bestProvider : 
            //    gps : GPS機能　LocationManager.GPS_PROVIDER　（実機室内では位置情報更新できず）
            //    network : 無線ネットワーク　（実機のみ位置情報更新可能:ただしgpsは未指定の場合）

            // キャッシュ位置情報の取得
            currentLocation = manager.getLastKnownLocation(bestProvider);

            updateNewLocation(currentLocation);

            controller.setZoom(15);
            //map.invalidate();

            // 位置情報の更新
            manager.requestLocationUpdates(bestProvider, MIN_TIME, MIN_DISTANCE, locationListener);
        }

        // 「設定」ボタン
        Button setting = (Button) findViewById(R.id.mysetting);
        setting.setOnClickListener(getSettingButtonClickListener());

        // 「Wowooooooo!」ボタン
        Button btn = (Button) findViewById(R.id.mybutton);
        btn.setOnClickListener(getWowButtonClickListener());
    }


    private LocationListener locationListener = new LocationListener() {

        /*
         * 位置情報が更新された時の処理
         * (non-Javadoc)
         * @see android.location.LocationListener#onLocationChanged(android.location.Location)
         */
        @Override
        public void onLocationChanged(Location location) {
            // TODO Auto-generated method stub
            Log.d(TAG, "onLocationChanged");
            currentLocation = location;
            updateNewLocation(location);
        }

        @Override
        public void onProviderDisabled(String provider) {
            // TODO Auto-generated method stub		
        }

        @Override
        public void onProviderEnabled(String provider) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            // TODO Auto-generated method stub

        }

    };


    /*
     * 現在位置情報更新
     * 地図スクロール：現在位置中心
     */
    private void updateNewLocation(Location location) {

        if (location == null) {
            Log.d(TAG, "location none");

            DialogUtils.AlertDialog(DevCampTeamAActivity.this, getResources().getString(R.string.dialog_error_location_titile), getResources().getString(R.string.dialog_error_location_message)).show();
            return;
        }

        Log.d(TAG, "location ok");
        latitude = (float) location.getLatitude();
        longitude = (float) location.getLongitude();
        //locationName = "";

        int lat = (int) (latitude * 1E6);
        int lng = (int) (longitude * 1E6);
        Log.d(TAG, "latitude : " + String.valueOf(latitude));
        Log.d(TAG, "longitude : " + String.valueOf(longitude));
        Log.d(TAG, "lat : " + String.valueOf(lat));
        Log.d(TAG, "lng : " + String.valueOf(lng));
        
        Log.d(TAG, String.format("%s, %s", WowoooooooUtils.decimal2sexagesimal(latitude), WowoooooooUtils.decimal2sexagesimal(longitude)));
        
        WowoooooooUtils.toastLocation(DevCampTeamAActivity.this, latitude, longitude, locationName);

        GeoPoint point = new GeoPoint(lat, lng);
        
        WowoooooooUserData userData = new WowoooooooUserData();
        userData.setUserName(preference.getNickName());
        userData.setTwitterId(preference.getTwitterId());
        userData.setLatitude(latitude);
        userData.setLongitude(longitude);
        userData.setLocationName(locationName); 
        List<WowoooooooUserData> userList = new ArrayList<WowoooooooUserData>();
        userList.add(userData);
        PinItemOverlay pinOverlay = new PinItemOverlay(getResources().getDrawable(R.drawable.pin_g), userList);
        pinOverlay.setContext(this);
        pinOverlay.setMapController(controller);     
        if (map.getOverlays().size() > 0) {
        	// ひとまず、現在地限定：常に 1　overlay としておく。
        	 map.getOverlays().remove(0);
        }
        map.getOverlays().add(pinOverlay);        
        Log.d(TAG, "size : " + map.getOverlays().size());
       
        //controller.setCenter(point);
        controller.animateTo(point);
    }

    /**
     * onKeyDown での　イベント制御
     * 戻るボタン機能のカスタマイズ
     * 再度「設定」「リスト」画面等に遷移させないための処理
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
    	/*
        if (keyCode == KeyEvent.KEYCODE_BACK) {

            Log.d(TAG, "onKeyDown : " + String.valueOf(keyCode));

            // [ホーム]ボタンの挙動と同じにする
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_HOME);
            startActivity(intent);
            
            // メインアクティビティ を終了 
            finish();
            // アプリ全体終了（中断状態） 
            moveTaskToBack(true);

            // [バック]ｷｰの場合、イベントを消費させるためにtrueを返す
            return true;
        }
        */
        // その他のイベントはデフォルト処理：チェインを伝播
        return super.onKeyDown(keyCode, event);
    }

    /**
     * 戻るボタンの処理.
     * アプリ終了
     */
    @Override
    public void onBackPressed() {
    	Log.d(TAG, "onBackPressed");
        super.onBackPressed();

        // メインアクティビティ を終了 
    	//finish();

        // アプリ全体終了（中断状態）
        moveTaskToBack(true);
    }

    /**
     * 設定ボタンを押したときのコールバックするリスナーを取得する.<br/>
     * 以下の動作をする.<br/>
     * <ul
     * <li>設定画面へ遷移する</li>
     * </ul>
     * 
     * @return 設定ボタンのリスナー
     */
    OnClickListener getSettingButtonClickListener() {
        return new OnClickListener() {

            @Override
            public void onClick(View v) {
                //Toast.makeText(DevCampTeamAActivity.this, "to setting", Toast.LENGTH_SHORT).show();
                Intent intent = new Intent();
                intent.setClassName("devcamp.team", "devcamp.team.SettingActivity");
                DevCampTeamAActivity.this.startActivity(intent);
            }
        };
    }

    /**
     * Wowooooooo! ボタンを押したときにコールバックするリスナーを取得する.<br/>
     * 以下の動作をする.<br/>
     * <ul>
     * <li>プリファレンス登録内容の取得</li>
     * <li>バリデーションで内容を確認する</li>
     * <li>内容に問題無い場合、設定を保存する</li>
     * <li>チェックに引っ掛かった場合、ダイアログを表示する。（設定を促す等）</li>
     * <li>現在の場所でのWowoooooooリスト表示画面へ遷移する。</li>
     * <ul>
     * @return Wowoooooooボタンのリスナー
     */
    OnClickListener getWowButtonClickListener() {
        return new OnClickListener() {

            @Override
            public void onClick(View v) {

                long uniqueId = preference.getUniqueId();

                Log.d(TAG, "uniqueId : " + String.valueOf(uniqueId));
                Log.d(TAG, "nickname : " + preference.getNickName());
                Log.d(TAG, "twitterId : " + preference.getTwitterId());
                Log.d(TAG, "latitude : " + String.valueOf(latitude));
                Log.d(TAG, "longitude : " + String.valueOf(longitude));
                Log.d(TAG, "locationName : " + locationName);

                if (uniqueId == -1) {
                    DialogUtils.AlertDialog(DevCampTeamAActivity.this, getResources().getString(R.string.dialog_error_wowooooooo_titile), getResources().getString(R.string.dialog_error_wowooooooo_message)).show();
                } else if (currentLocation == null) {
                    DialogUtils.AlertDialog(DevCampTeamAActivity.this, getResources().getString(R.string.dialog_error_location_titile), getResources().getString(R.string.dialog_error_location_message)).show();
                } else {
                    // Use AsyncTask!!
                    WowoooooooAsyncTask wowTask = new WowoooooooAsyncTask(DevCampTeamAActivity.this, uniqueId, latitude, longitude, locationName);

                    // 成功時のみ削除に変更
                    //LinearLayout l = (LinearLayout) findViewById(R.id.topmap);

                    //l.removeAllViews();
                    
                    wowTask.execute();
                }
            }

        };
    }

    @Override
    protected boolean isRouteDisplayed() {
        // TODO Auto-generated method stub
        return false;
    }

}
